﻿using AntUnion.FrameWork.Model;
using AntUnion.FrameWork.Model.Models;
using AntUnion.FrameWork.Model.ModelsExt;
using AntUnion.FrameWork.Web.IService;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using TencentCloud.Tcr.V20190924.Models;
using TencentCloud.Tdmq.V20200217.Models;
using TencentCloud.Ame.V20190916.Models;
using TencentCloud.Mrs.V20200910.Models;
using AntUnion.FrameWork.Web.Extend;
using NPOI.SS.Formula.Functions;
using static NPOI.HSSF.Util.HSSFColor;
using static AntUnion.FrameWork.Web.Controllers.AssetsController;
using AntUnion.FrameWork.Web.Common;
using Util.Extension;
using Quartz.Impl.Triggers;
using MetaQuotes.MT5WebAPI.Common;
using TencentCloud.Privatedns.V20201028.Models;

namespace AntUnion.FrameWork.Web.Service
{
    /// <summary>
    /// 资产相关业务类
    /// </summary>
    public class AssetsServer : IAssetsService
    {

        public List<string> GetCurrency()
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    List<string> list = mtContext.Currencies.Where(k => k.State == 1).OrderBy(k => k.Sort).Select(k => k.Currency1).Distinct().ToList();
                    return list;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取收款信息
        /// </summary>
        /// <param name="id"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public DepositCollection GetCollection(int id, int type)
        {
            try
            {
                DepositCollection obj = new DepositCollection();
                using (mtContext mtContext = new mtContext())
                {
                    if (type == (int)DepositType.WireTransfer)
                    {
                        WireTransfer wireTransfer = mtContext.WireTransfers.FirstOrDefault(k => k.Id == id);
                        obj.Id = wireTransfer.Id;
                        obj.Minimum = wireTransfer.Minimum;
                        obj.Maximum = wireTransfer.Maximum;
                    }
                    else if (type == (int)DepositType.RemittanceAccount)
                    {
                        RemittanceAccount remittanceAccount = mtContext.RemittanceAccounts.FirstOrDefault(k => k.Id == id);
                        obj.Id = remittanceAccount.Id;
                        obj.Minimum = remittanceAccount.Minimum;
                        obj.Maximum = remittanceAccount.Maximum;
                    }
                    else if (type == (int)DepositType.CryptoCurrency)
                    {
                        Cryptocurrency cryptocurrencie = mtContext.Cryptocurrencies.FirstOrDefault(k => k.Id == id);
                        obj.Id = cryptocurrencie.Id;
                        obj.Minimum = cryptocurrencie.Minimum;
                        obj.Maximum = cryptocurrencie.Maximum;
                    }
                    return obj;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        public class DepositCollection
        {
            public int Id { get; set; }
            public decimal? Minimum { get; set; }
            public decimal? Maximum { get; set; }
        }

        /// <summary>
        /// 获取收款信息
        /// </summary>
        /// <param name="id"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public object GetCrmCollection(int id, int type)
        {
            try
            {
                object obj = null;
                using (mtContext mtContext = new mtContext())
                {
                    if (type == (int)DepositType.WireTransfer)
                    {
                        obj = mtContext.CrmWireTransfers.FirstOrDefault(k => k.Id == id);
                    }
                    else if (type == (int)DepositType.RemittanceAccount)
                    {
                        obj = mtContext.CrmRemittanceAccounts.FirstOrDefault(k => k.Id == id);
                    }
                    else if (type == (int)DepositType.CryptoCurrency)
                    {
                        obj = mtContext.CrmCryptocurrencies.FirstOrDefault(k => k.Id == id);
                    }
                    return obj;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取出入金汇率
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <returns></returns>
        public ExchangeRate GetExchangeRate(string from, string to)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    ExchangeRate res = new ExchangeRate();
                    //相同币种返回1
                    if (from == to)
                    {
                        res.From = from;
                        res.To = to;
                        res.Price = 1;
                    }
                    else
                    {

                        ExchangeRate exchangeRate = mtContext.ExchangeRates.FirstOrDefault(k => k.From == from && k.To == to);
                        if (exchangeRate == null)
                        {
                            //可能存在from和to位置相反的情况，所以参数反过来再查一次
                            exchangeRate = mtContext.ExchangeRates.FirstOrDefault(k => k.From == to && k.To == from);
                        }
                        //查询不到返回空
                        if (exchangeRate == null)
                        {
                            return null;
                        }
                        else
                        {
                            res.From = exchangeRate.From;
                            res.To = exchangeRate.To;
                            res.Price = exchangeRate.Price;
                        }
                    }
                    return res;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 费用计算
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="amount"></param>
        /// <returns></returns>
        public RealAmount Commission(string from, string to, decimal amount)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    RealAmount realAmount = new RealAmount();
                    ExchangeRate exchangeRate = GetExchangeRate(from, to);
                    if (exchangeRate == null)
                    { return null; }
                    realAmount.Commission = 0;
                    realAmount.CurrencyPair = $"{exchangeRate.From}/{exchangeRate.To}";
                    realAmount.DepositAmount = amount;
                    realAmount.Rate = exchangeRate.Price;
                    decimal payAmount = 0;
                    if (from == exchangeRate.From)
                    {
                        payAmount = realAmount.DepositAmount / realAmount.Rate;

                    }
                    else
                    {
                        payAmount = realAmount.DepositAmount * realAmount.Rate;
                    }
                    //向上做四舍五入
                    realAmount.PayAmount = Math.Round(payAmount, 2, MidpointRounding.AwayFromZero);
                    return realAmount;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 入金.
        /// </summary>
        /// <param name="crmDeposit"></param>
        /// <returns></returns>
        public int Deposit(ref CrmDeposit crmDeposit)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    mtContext.CrmDeposits.Add(crmDeposit);
                    int count = mtContext.SaveChanges();
                    return count;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 出金.
        /// </summary>
        /// <param name="crmDeposit"></param>
        /// <returns></returns>
        public int Withdrawal(ref CrmWithdrawal crmWithdrawal)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    mtContext.CrmWithdrawals.Add(crmWithdrawal);
                    int count = mtContext.SaveChanges();
                    return count;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        public int GetWithdrawalCount(int crmId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    mtContext.CrmWithdrawals.Where(x => x.CrmId == crmId && x.State == 0).Count();
                    int count = mtContext.SaveChanges();
                    return count;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        #region 个人收款通道

        #region 电汇账户
        /// <summary>
        /// 获取我的电汇账户列表
        /// </summary>
        /// <param name="crmId"></param>
        /// <returns></returns>
        public List<CrmWireTransfer> GetCrmWireTransfers(int crmId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    List<CrmWireTransfer> crmWireTransfers = mtContext.CrmWireTransfers.Where(k => k.CrmId == crmId).ToList();
                    return crmWireTransfers;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取我的电汇账户
        /// </summary>
        /// <param name="crmId"></param>
        /// <returns></returns>
        public CrmWireTransfer GetCrmWireTransfers(int id, int crmId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    CrmWireTransfer crmWireTransfer = mtContext.CrmWireTransfers.Where(k => k.Id == id && k.CrmId == crmId).FirstOrDefault();
                    return crmWireTransfer;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 创建我的电汇账户
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int CreateWireTransfer(CrmWireTransfer model)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    mtContext.CrmWireTransfers.Add(model);
                    return mtContext.SaveChanges();
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 修改我的电汇账户
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int EditWireTransfer(CrmWireTransfer model)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    CrmWireTransfer crmWireTransfer = mtContext.CrmWireTransfers.FirstOrDefault(k => k.Id == model.Id);
                    crmWireTransfer.Currency = model.Currency;
                    crmWireTransfer.Payee = model.Payee;
                    crmWireTransfer.AccountNumber = model.AccountNumber;
                    crmWireTransfer.PayeeAddress = model.PayeeAddress;
                    crmWireTransfer.Bank = model.Bank;
                    crmWireTransfer.Swiftcode = model.Swiftcode;
                    crmWireTransfer.BankAddress = model.BankAddress;
                    return mtContext.SaveChanges();
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 删除我的电汇账户
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int DelWireTransfer(int id, int crmId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    CrmWireTransfer crmWireTransfer = mtContext.CrmWireTransfers.FirstOrDefault(k => k.Id == id && k.CrmId == crmId);
                    mtContext.CrmWireTransfers.Remove(crmWireTransfer);
                    return mtContext.SaveChanges();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取我的电汇账户
        /// </summary>
        /// <param name="crmId"></param>
        /// <returns></returns>
        public CrmWireTransfer GetMyWireTransfer(string accountNumber)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    CrmWireTransfer crmWireTransfer = mtContext.CrmWireTransfers.Where(k => k.AccountNumber == accountNumber).FirstOrDefault();
                    return crmWireTransfer;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        #endregion

        #region 汇款账户
        /// <summary>
        /// 获取我的汇款账户列表
        /// </summary>
        /// <param name="crmId"></param>
        /// <returns></returns>
        public List<CrmRemittanceAccount> GetCrmRemittanceAccounts(int crmId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    List<CrmRemittanceAccount> crmRemittanceAccounts = mtContext.CrmRemittanceAccounts.Where(k => k.CrmId == crmId).ToList();
                    return crmRemittanceAccounts;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取我的汇款账户
        /// </summary>
        /// <param name="crmId"></param>
        /// <returns></returns>
        public CrmRemittanceAccount GetCrmRemittanceAccount(int id, int crmId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    CrmRemittanceAccount crmRemittanceAccount = mtContext.CrmRemittanceAccounts.Where(k => k.Id == id && k.CrmId == crmId).FirstOrDefault();
                    return crmRemittanceAccount;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 创建我的汇款账户
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int CreateRemittanceAccount(CrmRemittanceAccount model)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    mtContext.CrmRemittanceAccounts.Add(model);
                    return mtContext.SaveChanges();
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 修改我的汇款账户
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int EditRemittanceAccount(CrmRemittanceAccount model)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    CrmRemittanceAccount crmRemittanceAccount = mtContext.CrmRemittanceAccounts.FirstOrDefault(k => k.Id == model.Id);
                    crmRemittanceAccount.Currency = model.Currency;
                    crmRemittanceAccount.Payee = model.Payee;
                    crmRemittanceAccount.AccountNumber = model.AccountNumber;
                    crmRemittanceAccount.Bank = model.Bank;
                    crmRemittanceAccount.BranchName = model.BranchName;
                    crmRemittanceAccount.Qrcode = model.Qrcode;
                    return mtContext.SaveChanges();
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 删除我的汇款账户
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int DelRemittanceAccount(int id, int crmId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    CrmRemittanceAccount crmRemittanceAccount = mtContext.CrmRemittanceAccounts.FirstOrDefault(k => k.Id == id && k.CrmId == crmId);
                    mtContext.CrmRemittanceAccounts.Remove(crmRemittanceAccount);
                    return mtContext.SaveChanges();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取我的汇款账户
        /// </summary>
        /// <param name="crmId"></param>
        /// <returns></returns>
        public CrmRemittanceAccount GetMyRemittanceAccount(string accountNumber)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    CrmRemittanceAccount crmRemittanceAccount = mtContext.CrmRemittanceAccounts.Where(k => k.AccountNumber == accountNumber).FirstOrDefault();
                    return crmRemittanceAccount;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }
        #endregion

        #region 加密货币
        /// <summary>
        /// 获取我的加密货币
        /// </summary>
        /// <param name="crmId"></param>
        /// <returns></returns>
        public List<CrmCryptocurrency> GetCrmCryptocurrencys(int crmId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    List<CrmCryptocurrency> crmCryptocurrencies = mtContext.CrmCryptocurrencies.Where(k => k.CrmId == crmId).ToList();
                    return crmCryptocurrencies;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取我的加密货币
        /// </summary>
        /// <param name="crmId"></param>
        /// <returns></returns>
        public CrmCryptocurrency GetCrmCryptocurrencys(int id, int crmId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    CrmCryptocurrency crmCryptocurrencie = mtContext.CrmCryptocurrencies.Where(k => k.Id == id && k.CrmId == crmId).FirstOrDefault();
                    return crmCryptocurrencie;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 创建我的加密货币
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int CreateCryptocurrency(CrmCryptocurrency model)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    mtContext.CrmCryptocurrencies.Add(model);
                    return mtContext.SaveChanges();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 修改我的加密货币
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int EditCryptocurrency(CrmCryptocurrency model)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    CrmCryptocurrency crmCryptocurrency = mtContext.CrmCryptocurrencies.FirstOrDefault(k => k.Id == model.Id);
                    crmCryptocurrency.Currency = model.Currency;
                    crmCryptocurrency.Network = model.Network;
                    crmCryptocurrency.ReceivingAddress = model.ReceivingAddress;
                    return mtContext.SaveChanges();
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 删除我的加密货币
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int DelCryptocurrency(int id, int crmId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    CrmCryptocurrency crmCryptocurrency = mtContext.CrmCryptocurrencies.FirstOrDefault(k => k.Id == id && k.CrmId == crmId);
                    mtContext.CrmCryptocurrencies.Remove(crmCryptocurrency);
                    return mtContext.SaveChanges();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取我的加密货币
        /// </summary>
        /// <param name="crmId"></param>
        /// <returns></returns>
        public CrmCryptocurrency GetMyCryptocurrency(string network)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    CrmCryptocurrency crmCryptocurrencie = mtContext.CrmCryptocurrencies.Where(k => k.Network == network).FirstOrDefault();
                    return crmCryptocurrencie;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }
        #endregion


        #endregion

        #region 平台入金通道

        /// <summary>
        /// 获取可用的电子账户
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public List<WireTransfer> GetWireTransfer(int? roleId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    if (roleId == 0)
                    {
                        roleId = null;
                    }
                    List<WireTransfer> wireTransferList = mtContext.WireTransfers.Where(k => k.Status == 1 && (k.RoleId == null || k.RoleId == roleId)).OrderBy(k => k.Sort).ToList();
                    return wireTransferList;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取可用的汇款账户
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public List<RemittanceAccount> GetRemittanceAccount(int? roleId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    if (roleId == 0)
                    {
                        roleId = null;
                    }
                    List<RemittanceAccount> remittanceAccountList = mtContext.RemittanceAccounts.Where(k => k.Status == 1 && (k.RoleId == null || k.RoleId == roleId)).OrderBy(k => k.Sort).ToList();
                    return remittanceAccountList;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取可用的加密货币列表
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public List<Cryptocurrency> GetCryptoCurrency(int? roleId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    if (roleId == 0)
                    {
                        roleId = null;
                    }
                    List<Cryptocurrency> cryptocurrencyList = mtContext.Cryptocurrencies.Where(k => k.Status == 1 && (k.RoleId == null || k.RoleId == roleId)).OrderBy(k => k.Sort).ToList();
                    return cryptocurrencyList;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        #endregion

        #region 资金流水

        public class WalleStatementModel
        {
            public string loginName { get; set; }
            public string name { get; set; }
            public string crmId { get; set; }
            public string login { get; set; }
            public string orderNumber { get; set; }
            public string operationType { get; set; }
            public string operationMode { get; set; }
            public string beforeAmount { get; set; }
            public string changeAmount { get; set; }
            public string afterAmount { get; set; }
            public DateTime changeTime { get; set; }
            public string currency { get; set; }
            public string walletId { get; set; }
            public string orderId { get; set; }
            public string from { get; set; }
            public string to { get; set; }
            public string reviewer { get; set; }
            public DateTime? overDate { get; set; }
            public string remark { get; set; }
            public string aduitRemark { get; set; }
        }

        /// <summary>
        /// 获取全部流水
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="crmId"></param>
        /// <param name="type"></param>
        /// <param name="mode"></param>
        /// <param name="walletId"></param>
        /// <param name="id"></param>
        /// <param name="datetime"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public List<WalleStatementModel> GetWalleStatement(int page, int limit, int crmId, string type, string mode, string walletId, string id, string datetime, out int count)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    var data = from wt in mtContext.CrmWalletTransactions
                               join w in mtContext.CrmWallets.Where(k => k.CrmId == crmId) on wt.WalletId equals w.Id
                               select new WalleStatementModel
                               {
                                   orderNumber = wt.Id,
                                   operationType = wt.Type,
                                   operationMode = wt.Mode,
                                   beforeAmount = wt.BeforeAmount.ToString("#,##0.00"),
                                   changeAmount = wt.Amount.ToString("#,##0.00"),
                                   afterAmount = wt.AfterAmount.ToString("#,##0.00"),
                                   changeTime = wt.CreateDate,
                                   currency = w.Currency,
                                   walletId = w.Id
                               };
                    if (!string.IsNullOrEmpty(type))
                    {
                        data = data.Where(k => k.operationType == type);
                    }
                    if (!string.IsNullOrEmpty(mode))
                    {
                        data = data.Where(k => k.operationMode == mode);
                    }
                    if (!string.IsNullOrEmpty(walletId))
                    {
                        data = data.Where(k => k.walletId == walletId);
                    }
                    if (!string.IsNullOrEmpty(id))
                    {
                        data = data.Where(k => k.orderNumber.Contains(id));
                    }
                    if (!string.IsNullOrEmpty(datetime) && datetime.Contains(" - "))
                    {
                        string[] dateTimes = datetime.Split(new string[] { " - " }, StringSplitOptions.None);
                        DateTime startTime = Convert.ToDateTime(dateTimes[0]);
                        DateTime endTime = Convert.ToDateTime(dateTimes[1]);
                        data = data.Where(k => k.changeTime > startTime && k.changeTime < endTime);
                    }
                    count = data.Count();
                    return data.OrderByDescending(k => k.changeTime).Skip((page - 1) * limit).Take(limit).ToList();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取全部流水
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="crmId"></param>
        /// <param name="type"></param>
        /// <param name="mode"></param>
        /// <param name="walletId"></param>
        /// <param name="id"></param>
        /// <param name="datetime"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public WalleStatementModel GetWalleStatementDetail(string id, int crmId)
        {
            try
            {
                WalleStatementModel walleStatementModel = new WalleStatementModel();
                using (mtContext mtContext = new mtContext())
                {
                    CrmWalletTransaction infoData = mtContext.CrmWalletTransactions.Find(id);
                    if (infoData == null)
                    {
                        return null;
                    }

                    walleStatementModel.orderNumber = infoData.Id;
                    walleStatementModel.operationType = infoData.Type;
                    walleStatementModel.operationMode = infoData.Mode;
                    walleStatementModel.beforeAmount = infoData.BeforeAmount.ToString("#,##0.00");
                    walleStatementModel.changeAmount = infoData.Amount.ToString("#,##0.00");
                    walleStatementModel.afterAmount = infoData.AfterAmount.ToString("#,##0.00");
                    walleStatementModel.changeTime = infoData.CreateDate;
                    walleStatementModel.walletId = infoData.Id;
                    walleStatementModel.remark = infoData.Remark;
                    CrmWallet model = mtContext.CrmWallets.Find(infoData.WalletId);
                    if (model != null)
                    {
                        CrmUser crmUser = mtContext.CrmUsers.Where(k => k.Id == model.CrmId).FirstOrDefault();
                        walleStatementModel.name = crmUser.Name;
                        walleStatementModel.loginName = crmUser.LoginName;
                        walleStatementModel.crmId = crmUser.Id.ToString();
                        walleStatementModel.login = mtContext.Mt5Users.Any(k => k.CrmId == model.CrmId) ? $"{mtContext.Mt5Users.First(k => k.CrmId == model.CrmId).Login}" : "";
                        CrmInternaltransfer internaltransfer = mtContext.CrmInternaltransfers.FirstOrDefault(k => k.Id == infoData.OrderId);
                        if (internaltransfer != null)
                        {
                            walleStatementModel.remark = internaltransfer.Remark;
                            CrmAuditLog auditLog = mtContext.CrmAuditLogs.Where(k => k.OrderId == internaltransfer.Id && !string.IsNullOrEmpty(k.ReviewerId.ToString())).FirstOrDefault();
                            if (auditLog != null)
                            {
                                walleStatementModel.aduitRemark = auditLog.Remark;
                                walleStatementModel.reviewer = mtContext.TbUsers.FirstOrDefault(k => k.Id == auditLog.ReviewerId).LoginName;
                                walleStatementModel.overDate = auditLog.CreateDate;
                            }
                            else
                            {
                                walleStatementModel.aduitRemark = infoData.Remark;
                                walleStatementModel.reviewer = infoData.Creator;
                                walleStatementModel.overDate = infoData.CreateDate;
                            }
                        }
                        else
                        {
                            walleStatementModel.remark = "";
                            walleStatementModel.aduitRemark = infoData.Remark;
                            walleStatementModel.reviewer = infoData.Creator;
                            walleStatementModel.overDate = infoData.CreateDate;
                        }
                    }
                    else
                    {
                        walleStatementModel.name = "";
                        walleStatementModel.loginName = "";
                        walleStatementModel.login = "";
                        walleStatementModel.aduitRemark = infoData.Remark;
                        walleStatementModel.reviewer = infoData.Creator;
                        walleStatementModel.overDate = infoData.CreateDate;
                    }
                    //var data = from wt in mtContext.CrmWalletTransactions.Where(k => k.Id == id)
                    //           join w in mtContext.CrmWallets.Where(k => k.CrmId == crmId) on wt.WalletId equals w.Id
                    //           join crm in mtContext.CrmUsers.Where(k => k.Id == crmId) on w.CrmId equals crm.Id
                    //           join it in mtContext.CrmInternaltransfers on wt.OrderId equals it.Id into aduit
                    //           from aduitData in aduit.DefaultIfEmpty()
                    //           select new WalleStatementModel
                    //           {
                    //               loginName = crm.LoginName,
                    //               name = crm.Name,
                    //               crmId = w.Id,
                    //               orderNumber = wt.Id,
                    //               operationType = wt.Type,
                    //               operationMode = wt.Mode,
                    //               beforeAmount = wt.BeforeAmount.ToString("#,##0.00"),
                    //               changeAmount = wt.Amount.ToString("#,##0.00"),
                    //               afterAmount = wt.AfterAmount.ToString("#,##0.00"),
                    //               changeTime = wt.CreateDate,
                    //               currency = w.Currency,
                    //               walletId = w.Id,
                    //               remark = wt.Remark,
                    //               reviewer = aduitData.Reviewer,
                    //               overDate = aduitData.OverDate,
                    //               aduitRemark = mtContext.CrmAuditLogs.Where(k => k.OrderId == aduitData.Id && !string.IsNullOrEmpty(k.ReviewerId.ToString())).OrderByDescending(k => k.Id).Select(k => k.Remark).FirstOrDefault()
                    //           };

                    //walleStatementModel = data.FirstOrDefault();
                    return walleStatementModel;
                }
            }
            catch (Exception)
            {
                throw;
            }
        }


        #endregion

        #region 交易账号资金流水

        public class TradingStatemengModel
        {
            public string tradingAccountNo { get; set; }
            public string name { get; set; }
            public string operationType { get; set; }
            public int crmId { get; set; }
            public string loginName { get; set; }
            public string serialNumber { get; set; }
            public string changeAmount { get; set; }
            public string receivedAmount { get; set; }
            public string commission { get; set; }
            public DateTime changeTime { get; set; }
            public string currency { get; set; }
            public string orderNumber { get; set; }
            public string remark { get; set; }
            public string reviewer { get; set; }
            public string aduitRemark { get; set; }
            public string auditTime { get; set; }
        }

        /// <summary>
        /// 资金账号交易流水
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="operationType"></param>
        /// <param name="serialNumber"></param>
        /// <param name="changeTime"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public List<TradingStatemengModel> GetTradingStatemeng(int page, int limit, int crmId, string operationType, string orderNumber, string changeTime, out int count)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    var data = from crm in mtContext.CrmUsers.Where(k => k.Id == crmId)
                               join mt5 in mtContext.Mt5Users on crm.Id equals mt5.CrmId
                               join trad in mtContext.Mt5Transactions on mt5.Login equals trad.Login
                               select new TradingStatemengModel
                               {
                                   tradingAccountNo = mt5.Login.ToString(),
                                   name = crm.Name,
                                   loginName = crm.LoginName,
                                   operationType = trad.Type,
                                   crmId = crm.Id,
                                   orderNumber = trad.Id,
                                   changeAmount = trad.Amount.ToString("#,##0.00"),
                                   receivedAmount = trad.Toamount == null ? "" : ((decimal)trad.Toamount).ToString("#,##0.00"),
                                   commission = trad.Fees.ToString("#,##0.00"),
                                   changeTime = (DateTime)trad.CreateDate,
                                   currency = "USD",
                                   serialNumber = trad.OrderId,
                                   reviewer = trad.Type == "rechargeAndDeposit" ? mtContext.CrmDeposits.Where(k => k.Mt5Order == trad.OrderId && k.State == 2).Select(k => k.Reviewer).FirstOrDefault() : trad.Type == "withdrawalOfFunds" ? mtContext.CrmWithdrawals.Where(k => k.Mt5Order == trad.OrderId && k.State == 2).Select(k => k.Reviewer).FirstOrDefault() : trad.Type == "internalTransferIn" ? mtContext.CrmInternaltransfers.Where(k => k.Mt5Order == trad.OrderId && k.State == 2).Select(k => k.Reviewer).FirstOrDefault() : (trad.Type == "systemDeposit" || trad.Type == "systemWithdrawal") ? trad.Creator : "",
                                   auditTime = trad.Type == "rechargeAndDeposit" ? mtContext.CrmDeposits.Where(k => k.Mt5Order == trad.OrderId && k.State == 2).Select(k => k.OverDate).FirstOrDefault().ToString() : trad.Type == "withdrawalOfFunds" ? mtContext.CrmWithdrawals.Where(k => k.Mt5Order == trad.OrderId && k.State == 2).Select(k => k.OverDate).FirstOrDefault().ToString() : trad.Type == "internalTransferIn" ? mtContext.CrmInternaltransfers.Where(k => k.Mt5Order == trad.OrderId && k.State == 2).Select(k => k.OverDate).FirstOrDefault().ToString() : (trad.Type == "systemDeposit" || trad.Type == "systemWithdrawal") ? trad.CreateDate.ToString() : "",
                                   aduitRemark = trad.Type == "rechargeAndDeposit" ? mtContext.CrmDeposits.Where(k => k.Mt5Order == trad.OrderId && k.State == 2).Select(k => k.Remark).FirstOrDefault() : trad.Type == "withdrawalOfFunds" ? mtContext.CrmWithdrawals.Where(k => k.Mt5Order == trad.OrderId && k.State == 2).Select(k => k.Remark).FirstOrDefault() : trad.Type == "internalTransferIn" ? mtContext.CrmInternaltransfers.Where(k => k.Mt5Order == trad.OrderId && k.State == 2).Select(k => k.Remark).FirstOrDefault() : trad.Remark,

                               };
                    if (!string.IsNullOrEmpty(operationType))
                    {
                        data = data.Where(k => k.operationType == operationType);
                    }
                    if (!string.IsNullOrEmpty(orderNumber))
                    {
                        data = data.Where(k => k.orderNumber.Contains(orderNumber));
                    }
                    if (!string.IsNullOrEmpty(changeTime) && changeTime.Contains(" - "))
                    {
                        string[] dateTimes = changeTime.Split(new string[] { " - " }, StringSplitOptions.None);
                        DateTime startTime = Convert.ToDateTime(dateTimes[0]);
                        DateTime endTime = Convert.ToDateTime(dateTimes[1]);
                        data = data.Where(k => k.changeTime > startTime && k.changeTime < endTime);
                    }
                    count = data.Count();
                    return data.OrderByDescending(k => k.changeTime).Skip((page - 1) * limit).Take(limit).ToList();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        #endregion

        #region 审核记录

        public class DepositModel
        {
            public string orderNumber { get; set; }
            public int operationMode { get; set; }
            public long depositAccount { get; set; }
            public int state { get; set; }
            public string fromAmount { get; set; }
            public string fromAmountCurrency { get; set; }
            public string toAmount { get; set; }
            public string toAmountCurrency { get; set; }
            public decimal exchangeRate { get; set; }
            public string depositAmount { get; set; }
            public string depositAmountCurrency { get; set; }
            public string fees { get; set; }
            public DateTime createDate { get; set; }
            public string reviewer { get; set; }
            public DateTime? overDate { get; set; }
            public string Certificate { get; set; }
            public string Info { get; set; }
            public string remark { get; set; }
            public string aduitRemark { get; set; }
        }

        /// <summary>
        /// 入金审核
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="login"></param>
        /// <param name="mothod"></param>
        /// <param name="state"></param>
        /// <param name="createTime"></param>
        /// <param name="orderId"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public List<DepositModel> GetDeposit(int page, int limit, int crmId, int? login, int? mothod, int? state, string createTime, string orderId, out int count)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    var data = from deposits in mtContext.CrmDeposits.AsNoTracking().Where(k => k.CrmId == crmId)
                               select new DepositModel
                               {
                                   orderNumber = deposits.Id,
                                   operationMode = deposits.Mothod,
                                   depositAccount = deposits.Login,
                                   state = deposits.State,
                                   fromAmount = deposits.FromAmount.ToString("#,##0.00"),
                                   fromAmountCurrency = deposits.FromAmountCurrency,
                                   toAmount = deposits.ToAmount.ToString("#,##0.00"),
                                   toAmountCurrency = deposits.ToAmountCurrency,
                                   exchangeRate = deposits.ExchangeRate,
                                   depositAmount = deposits.DepositAmount.ToString("#,##0.00"),
                                   depositAmountCurrency = deposits.DepositAmountCurrency,
                                   fees = deposits.Fees.ToString("#,##0.00"),
                                   createDate = deposits.CreateDate,
                                   reviewer = deposits.Reviewer,
                                   overDate = deposits.OverDate,
                                   Certificate = deposits.Certificate,
                                   remark = deposits.Remark,
                                   aduitRemark = mtContext.CrmAuditLogs.Where(k => k.OrderId == deposits.Id && !string.IsNullOrEmpty(k.ReviewerId.ToString())).OrderByDescending(k => k.Id).Select(k => k.Remark).FirstOrDefault()
                               };
                    if (login != null)
                    {
                        data = data.Where(k => k.depositAccount == login);
                    }
                    if (mothod != null)
                    {
                        data = data.Where(k => k.operationMode == mothod);
                    }
                    if (state != null)
                    {
                        data = data.Where(k => k.state == state);
                    }
                    if (orderId != null)
                    {
                        data = data.Where(k => k.orderNumber.Contains(orderId));
                    }
                    if (!string.IsNullOrEmpty(createTime) && createTime.Contains(" - "))
                    {
                        string[] dateTimes = createTime.Split(new string[] { " - " }, StringSplitOptions.None);
                        DateTime startTime = Convert.ToDateTime(dateTimes[0]);
                        DateTime endTime = Convert.ToDateTime(dateTimes[1]);
                        data = data.Where(k => k.createDate > startTime && k.createDate < endTime);
                    }
                    count = data.Count();
                    return data.OrderBy(k => k.state).ThenByDescending(k => k.createDate).Skip((page - 1) * limit).Take(limit).ToList();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        public class WithdrawalModel
        {
            public string orderNumber { get; set; }
            public int operationMode { get; set; }
            public long withdrawalAccount { get; set; }
            public int state { get; set; }
            public string fromAmount { get; set; }
            public string fromAmountCurrency { get; set; }
            public string toAmount { get; set; }
            public string toAmountCurrency { get; set; }
            public decimal exchangeRate { get; set; }
            public string withdrawalAmount { get; set; }
            public string withdrawalAmountCurrency { get; set; }
            public string fees { get; set; }
            public DateTime createDate { get; set; }
            public string reviewer { get; set; }
            public DateTime? overDate { get; set; }
            public ulong deducted { get; set; }
            public string account { get; set; }
            public string remark { get; set; }
            public string aduitRemark { get; set; }
        }

        /// <summary>
        /// 出金审核
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="login"></param>
        /// <param name="mothod"></param>
        /// <param name="state"></param>
        /// <param name="createTime"></param>
        /// <param name="orderId"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public List<WithdrawalModel> GetWithdrawal(int page, int limit, int crmId, int? login, int? mothod, int? state, string createTime, string orderId, out int count)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    var data = from withdrawal in mtContext.CrmWithdrawals.AsNoTracking().Where(k => k.CrmId == crmId)
                               select new WithdrawalModel
                               {
                                   orderNumber = withdrawal.Id,
                                   operationMode = withdrawal.Mothod,
                                   withdrawalAccount = withdrawal.Login,
                                   state = withdrawal.State,
                                   fromAmount = withdrawal.FromAmount.ToString("#,##0.00"),
                                   fromAmountCurrency = withdrawal.FromAmountCurrency,
                                   toAmount = withdrawal.ToAmount.ToString("#,##0.00"),
                                   toAmountCurrency = withdrawal.ToAmountCurrency,
                                   exchangeRate = withdrawal.ExchangeRate,
                                   withdrawalAmount = withdrawal.WithdrawalAmount.ToString("#,##0.00"),
                                   withdrawalAmountCurrency = withdrawal.WithdrawalAmountCurrency,
                                   fees = withdrawal.Fees.ToString("#,##0.00"),
                                   createDate = withdrawal.CreateDate,
                                   reviewer = withdrawal.Reviewer,
                                   overDate = withdrawal.OverDate,
                                   deducted = withdrawal.Deducted,
                                   remark = withdrawal.Remark,
                                   aduitRemark = mtContext.CrmAuditLogs.Where(k => k.OrderId == withdrawal.Id && !string.IsNullOrEmpty(k.ReviewerId.ToString())).OrderByDescending(k => k.Id).Select(k => k.Remark).FirstOrDefault()
                               };
                    if (login != null)
                    {
                        data = data.Where(k => k.withdrawalAccount == login);
                    }
                    if (mothod != null)
                    {
                        data = data.Where(k => k.operationMode == mothod);
                    }
                    if (state != null)
                    {
                        data = data.Where(k => k.state == state);
                    }
                    if (orderId != null)
                    {
                        data = data.Where(k => k.orderNumber.Contains(orderId));
                    }
                    if (!string.IsNullOrEmpty(createTime) && createTime.Contains(" - "))
                    {
                        string[] dateTimes = createTime.Split(new string[] { " - " }, StringSplitOptions.None);
                        DateTime startTime = Convert.ToDateTime(dateTimes[0]);
                        DateTime endTime = Convert.ToDateTime(dateTimes[1]);
                        data = data.Where(k => k.createDate > startTime && k.createDate < endTime);
                    }
                    count = data.Count();
                    return data.OrderBy(k => k.state).ThenByDescending(k => k.createDate).Skip((page - 1) * limit).Take(limit).ToList();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        #endregion

        #region 内部转账

        public partial class CrmInternaltransferModel
        {
            public string orderNumber { get; set; }
            public string transferOutAmount { get; set; }
            public string receivedAmount { get; set; }
            public int state { get; set; }
            public string fees { get; set; }
            public DateTime createDate { get; set; }
            public string reviewer { get; set; }
            public DateTime? overDate { get; set; }
            public string remark { get; set; }
            public string aduitRemark { get; set; }
        }

        public int GetInternaltransferCount(int crmId)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    mtContext.CrmInternaltransfers.Where(x => x.CrmId == crmId && x.State == 0).Count();
                    int count = mtContext.SaveChanges();
                    return count;
                }
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 添加钱包流水
        /// </summary>
        /// <param name="mtContext"></param>
        /// <param name="walletid"></param>
        /// <param name="balance"></param>
        /// <param name="amount"></param>
        public void AddWalletTransaction(mtContext mtContext, string walletid, string type, string mode, decimal balance, decimal amount, string orderid)
        {
            try
            {
                CrmWalletTransaction transaction = new CrmWalletTransaction
                {
                    Id = CommonHelper.GetOrderNo(),
                    WalletId = walletid,
                    Type = type,
                    Mode = mode,
                    BeforeAmount = balance,
                    OrderId = orderid,
                    CreateDate = DateTime.Now,
                };
                if (transaction.Mode == "internalTransferOut")
                {
                    transaction.Amount = 0 - amount;
                }
                else
                {
                    transaction.Amount = amount;
                }
                transaction.AfterAmount = transaction.BeforeAmount + transaction.Amount;
                mtContext.CrmWalletTransactions.Add(transaction);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 添加内部转账流水
        /// </summary>
        /// <param name="mtContext"></param>
        /// <param name="walletid"></param>
        /// <param name="balance"></param>
        /// <param name="amount"></param>
        public void AddCrmInternalTransfer(mtContext mtContext, int crmid, long login, string walletid, decimal balance, decimal amount, string remark, out string orderId)
        {
            try
            {
                CrmInternaltransfer crmInternaltransfer = new CrmInternaltransfer
                {
                    Id = CommonHelper.GetOrderNo(),
                    CrmId = crmid,
                    Login = login,
                    Walletid = walletid,
                    FromAmount = amount,
                    FromAmountCurrency = "USD",
                    ToAmount = amount,
                    ToAmountCurrency = "USD",
                    ExchangeRate = 1,
                    State = 0,
                    Fees = 0,
                    CreateDate = DateTime.Now,
                    Remark = remark
                };
                orderId = crmInternaltransfer.Id;
                mtContext.CrmInternaltransfers.Add(crmInternaltransfer);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 内部转账审核
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="login"></param>
        /// <param name="mothod"></param>
        /// <param name="state"></param>
        /// <param name="createTime"></param>
        /// <param name="orderId"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public List<CrmInternaltransferModel> GetInternalTransfer(int page, int limit, int crmId, int? state, string createTime, string orderId, out int count)
        {
            try
            {
                using (mtContext mtContext = new mtContext())
                {
                    var data = from internaltransfer in mtContext.CrmInternaltransfers.AsNoTracking().Where(k => k.CrmId == crmId)
                               select new CrmInternaltransferModel
                               {
                                   orderNumber = internaltransfer.Id,
                                   state = internaltransfer.State,
                                   transferOutAmount = internaltransfer.FromAmount.ToString("#,##0.00"),
                                   receivedAmount = internaltransfer.ToAmount.ToString("#,##0.00"),
                                   fees = internaltransfer.Fees.ToString("#,##0.00"),
                                   createDate = internaltransfer.CreateDate,
                                   reviewer = internaltransfer.Reviewer,
                                   overDate = internaltransfer.OverDate,
                                   remark = internaltransfer.Remark,
                                   aduitRemark = mtContext.CrmAuditLogs.Where(k => k.OrderId == internaltransfer.Id && !string.IsNullOrEmpty(k.ReviewerId.ToString())).OrderByDescending(k => k.Id).Select(k => k.Remark).FirstOrDefault()
                               };
                    if (state != null)
                    {
                        data = data.Where(k => k.state == state);
                    }
                    if (orderId != null)
                    {
                        data = data.Where(k => k.orderNumber.Contains(orderId));
                    }
                    if (!string.IsNullOrEmpty(createTime) && createTime.Contains(" - "))
                    {
                        string[] dateTimes = createTime.Split(new string[] { " - " }, StringSplitOptions.None);
                        DateTime startTime = Convert.ToDateTime(dateTimes[0]);
                        DateTime endTime = Convert.ToDateTime(dateTimes[1]);
                        data = data.Where(k => k.createDate > startTime && k.createDate < endTime);
                    }
                    count = data.Count();
                    return data.OrderBy(k => k.state).ThenByDescending(k => k.createDate).Skip((page - 1) * limit).Take(limit).ToList();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        #endregion

        /// <summary>
        /// 获取真实的可出金额
        /// </summary>
        /// <param name="mTAccount"></param>
        /// <returns></returns>
        public double GetRealBalance(MTAccount mTAccount)
        {
            try
            {
                double balance = (mTAccount.Balance > mTAccount.Equity ? mTAccount.Equity : mTAccount.Balance) - mTAccount.Margin;
                return balance < 0d ? 0d : balance;
            }
            catch (Exception)
            {
                return 0;
            }
        }
    }
}
